home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / graphics_libraries / primitives / WBClone.c < prev   
C/C++ Source or Header  |  1992-09-03  |  17KB  |  535 lines

  1. ;/*  WBClone.c: To clone the Workbench using graphics calls
  2. LC -b1 -cfist -v -j73 WBClone.c
  3. Blink FROM LIB:c.o,WBClone.o TO WBClone LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. Quit ;
  5.  
  6. Copyright (c) 1992 Commodore-Amiga, Inc.
  7.  
  8. This example is provided in electronic form by Commodore-Amiga, Inc. for
  9. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  10. published by Addison-Wesley (ISBN 0-201-56774-1).
  11.  
  12. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  13. information on the correct usage of the techniques and operating system
  14. functions presented in these examples.  The source and executable code
  15. of these examples may only be distributed in free electronic form, via
  16. bulletin board or as part of a fully non-commercial and freely
  17. redistributable diskette.  Both the source and executable code (including
  18. comments) must be included, without modification, in any copy.  This
  19. example may not be published in printed form or distributed with any
  20. commercial product.  However, the programming techniques and support
  21. routines set forth in these examples may be used in the development
  22. of original executable software products for Commodore Amiga computers.
  23.  
  24. All other rights reserved.
  25.  
  26. This example is provided "as-is" and is subject to change; no
  27. warranties are made.  All use is at your own risk. No liability or
  28. responsibility is assumed.
  29.  
  30. */
  31.  
  32. #include <exec/types.h>
  33. #include <exec/exec.h>
  34. #include <clib/exec_protos.h>
  35. #include <intuition/screens.h>
  36. #include <intuition/intuition.h>
  37. #include <intuition/intuitionbase.h>
  38. #include <clib/intuition_protos.h>
  39. #include <graphics/gfx.h>
  40. #include <graphics/gfxbase.h>
  41. #include <graphics/view.h>
  42. #include <graphics/gfxnodes.h>
  43. #include <graphics/videocontrol.h>
  44. #include <clib/graphics_protos.h>
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48.  
  49. #define INTUITIONNAME "intuition.library"
  50.  
  51. #ifdef LATTICE
  52. int CXBRK(void)    { return(0); }  /* Disable Lattice CTRL/C handling */
  53. int chkabort(void) { return(0); }  /* really */
  54. #endif
  55.  
  56.  
  57. /*********************************************************************/
  58. /*                            GLOBAL VARIABLES                       */
  59. /*********************************************************************/
  60.  
  61. struct IntuitionBase *IntuitionBase = NULL ;
  62. struct GfxBase *GfxBase = NULL ;
  63.  
  64. /**********************************************************************/
  65. /*                                                                    */
  66. /* VOID Error (char *String)                                          */
  67. /*                                                                    */
  68. /* Print string and exit                                              */
  69. /*                                                                    */
  70. /**********************************************************************/
  71.  
  72. VOID Error (char *String)
  73. {
  74.     VOID CloseAll (VOID) ;
  75.  
  76.     printf (String) ;
  77.  
  78.     CloseAll () ;
  79.     exit(0) ;
  80. }
  81.  
  82.  
  83. /**********************************************************************/
  84. /*                                                                    */
  85. /* VOID Init ()                                                       */
  86. /*                                                                    */
  87. /* Opens all the required libraries allocates all memory, etc.        */
  88. /*                                                                    */
  89. /**********************************************************************/
  90.  
  91. VOID Init ( VOID )
  92. {
  93.     /* Open the intuition library.... */
  94.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary (INTUITIONNAME, 37L)) == NULL)
  95.         Error ("Could not open the Intuition.library") ;
  96.  
  97.     /* Open the graphics library.... */
  98.     if ((GfxBase = (struct GfxBase *)OpenLibrary (GRAPHICSNAME, 37L)) == NULL)
  99.         Error ("Could not open the Graphics.library") ;
  100. }
  101.  
  102. /**********************************************************************/
  103. /*                                                                    */
  104. /* VOID CloseAll ()                                                   */
  105. /*                                                                    */
  106. /* Closes and tidies up everything that was used.                     */
  107. /*                                                                    */
  108. /**********************************************************************/
  109.  
  110. VOID CloseAll ( VOID )
  111. {
  112.     /* Close everything in the reverse order in which they were opened */
  113.  
  114.     /* Close the Graphics Library */
  115.     if (GfxBase)
  116.         CloseLibrary ((struct Library *) GfxBase) ;
  117.  
  118.     /* Close the Intuition Library */
  119.     if (IntuitionBase)
  120.         CloseLibrary ((struct Library *) IntuitionBase) ;
  121. }
  122. /**********************************************************************/
  123. /*                                                                    */
  124. /* VOID DestroyView(struct View *view)                                */
  125. /*                                                                    */
  126. /* Close and free everything to do with the View                      */
  127. /*                                                                    */
  128. /**********************************************************************/
  129.  
  130. VOID DestroyView(struct View *view)
  131. {
  132.     struct ViewExtra *ve;
  133.  
  134.     if (view)
  135.     {
  136.         if (ve = (struct ViewExtra *)GfxLookUp(view))
  137.         {
  138.             if (ve->Monitor)
  139.                 CloseMonitor(ve->Monitor);
  140.  
  141.             GfxFree((struct ExtendedNode *)ve);
  142.         }
  143.  
  144.         /* Free up the copper lists */
  145.         if (view->LOFCprList)
  146.             FreeCprList(view->LOFCprList);
  147.  
  148.         if (view->SHFCprList)
  149.             FreeCprList(view->SHFCprList);
  150.  
  151.         FreeVec(view);
  152.     }
  153. }
  154.  
  155. /**********************************************************************/
  156. /*                                                                    */
  157. /* struct View *DupView(struct View *v, ULONG ModeID)                 */
  158. /*                                                                    */
  159. /* Duplicate the View.                                                */
  160. /*                                                                    */
  161. /**********************************************************************/
  162.  
  163. struct View *DupView(struct View *v, ULONG ModeID)
  164. {
  165.     /* Allocate and init a View structure.  Also, get a ViewExtra
  166.      * structure and attach the monitor type to the View.
  167.      */
  168.  
  169.     struct View *view = NULL;
  170.     struct ViewExtra *ve = NULL;
  171.     struct MonitorSpec *mspc = NULL;
  172.  
  173.     if (view = AllocVec(sizeof(struct View), MEMF_PUBLIC | MEMF_CLEAR))
  174.     {
  175.         if (ve = GfxNew(VIEW_EXTRA_TYPE))
  176.         {
  177.             if (mspc = OpenMonitor(NULL, ModeID))
  178.             {
  179.                 InitView(view);
  180.                 view->DyOffset = v->DyOffset;
  181.                 view->DxOffset = v->DxOffset;
  182.                 view->Modes = v->Modes;
  183.                 GfxAssociate(view, (struct ExtendedNode *)ve);
  184.                 ve->Monitor = mspc;
  185.             }
  186.             else printf("Could not open monitor\n");
  187.         }
  188.         else printf("Could not get ViewExtra\n");
  189.     }
  190.     else printf("Could not create View\n");
  191.  
  192.     if (view && ve && mspc)
  193.         return(view);
  194.     else
  195.     {
  196.         DestroyView(view);
  197.         return(NULL);
  198.     }
  199. }
  200.  
  201.  
  202. /**********************************************************************/
  203. /*                                                                    */
  204. /* VOID DestroyViewPort(struct ViewPort *vp)                          */
  205. /*                                                                    */
  206. /* Close and free everything to do with the ViewPort.                 */
  207. /*                                                                    */
  208. /**********************************************************************/
  209.  
  210. VOID DestroyViewPort(struct ViewPort *vp)
  211. {
  212.     if (vp)
  213.     {
  214.         /* Find the ViewPort's ColorMap. From that use VideoControl
  215.          *  to get the ViewPortExtra, and free it.
  216.          * Then free the ColorMap, and finally the ViewPort itself.
  217.          */
  218.         struct ColorMap *cm = vp->ColorMap;
  219.         struct TagItem ti[] =
  220.         {
  221.             {VTAG_VIEWPORTEXTRA_GET, NULL},    /* <-- This field will be filled in */
  222.             {VTAG_END_CM, NULL}
  223.         };
  224.  
  225.         if (cm)
  226.         {
  227.             if (VideoControl(cm, ti) == NULL)
  228.                 GfxFree((struct ExtendedNode *)ti[0].ti_Data);
  229.             else
  230.                 printf("VideoControl error in DestroyViewPort()\n");
  231.  
  232.             FreeColorMap(cm);
  233.         }
  234.         else
  235.         {
  236.             printf("Could not free the ColorMap\n");
  237.         }
  238.  
  239.         FreeVPortCopLists(vp);
  240.  
  241.         FreeVec(vp);
  242.     }
  243. }
  244.  
  245. /**********************************************************************/
  246. /*                                                                    */
  247. /* struct ViewPort *DupViewPort(struct ViewPort *vp, ULONG ModeID)    */
  248. /*                                                                    */
  249. /* Duplicate the ViewPort.                                            */
  250. /*                                                                    */
  251. /**********************************************************************/
  252.  
  253. struct ViewPort *DupViewPort(struct ViewPort *vp, ULONG ModeID)
  254. {
  255.     /* Allocate and initialise a ViewPort. Copy the ViewPort width and
  256.      * heights, offsets, and modes values.  Allocate and initialize a
  257.      * ColorMap.
  258.      *
  259.      * Also, allocate a ViewPortExtra, and copy the TextOScan values of the
  260.      * ModeID from the database into the ViewPortExtra.
  261.      */
  262.  
  263.     #define COLOURS 32
  264.     struct ViewPort *Myvp;
  265.     struct ViewPortExtra *vpe;
  266.     struct ColorMap *cm;
  267.     struct TagItem ti[] =             /* to attach everything */
  268.     {
  269.         {VTAG_ATTACH_CM_SET, NULL},    /* these NULLs will be replaced in the code */
  270.         {VTAG_VIEWPORTEXTRA_SET, NULL},
  271.         {VTAG_NORMAL_DISP_SET, NULL},
  272.         {VTAG_END_CM, NULL}
  273.     };
  274.     struct DimensionInfo query = {0};
  275.     UWORD colour;
  276.     int c;
  277.     ULONG gotinfo = NULL;
  278.  
  279.     if (Myvp = AllocVec(sizeof(struct ViewPort), MEMF_CLEAR | MEMF_PUBLIC))
  280.     {
  281.         if (vpe = (struct ViewPortExtra *)GfxNew(VIEWPORT_EXTRA_TYPE))
  282.         {
  283.             if (cm = GetColorMap(32))
  284.             {
  285.                 if (gotinfo = GetDisplayInfoData(NULL, (APTR)&query,
  286.                                                                  sizeof(query), DTAG_DIMS, ModeID))
  287.                 {
  288.                     InitVPort(Myvp);
  289.  
  290.                     /* duplicate the ViewPort structure */
  291.                     Myvp->DWidth = vp->DWidth;
  292.                     Myvp->DHeight = vp->DHeight;
  293.                     Myvp->DxOffset = vp->DxOffset;
  294.                     Myvp->DyOffset = vp->DyOffset;
  295.                     Myvp->Modes = vp->Modes;
  296.                     Myvp->SpritePriorities = vp->SpritePriorities;
  297.                     Myvp->ExtendedModes = vp->ExtendedModes;
  298.  
  299.                     /* duplicate the Overscan values */
  300.                     vpe->DisplayClip = query.TxtOScan;
  301.  
  302.                     /* attach everything together */
  303.                     ti[0].ti_Data = (ULONG)Myvp;
  304.                     ti[1].ti_Data = (ULONG)vpe;
  305.                     ti[2].ti_Data = (ULONG)FindDisplayInfo(ModeID);
  306.                     if (VideoControl(cm, ti) != NULL)
  307.                     {
  308.                         printf("VideoControl error in CreateViewPort()\n");
  309.                     }
  310.  
  311.                     /* copy the colours from the workbench */
  312.                     for (c = 0; c < COLOURS; c++)
  313.                     {
  314.                         if ((colour = GetRGB4(vp->ColorMap, c)) != -1)
  315.                         {
  316.                         SetRGB4CM(cm, c, (colour >> 8),
  317.                               ((colour >> 4) & 0xf), (colour & 0xf));
  318.                         }
  319.                     }
  320.                 }
  321.                 else printf("Database error\n");
  322.             }
  323.             else printf("Could not get the ColorMap\n");
  324.         }
  325.         else printf("Could not get the ViewPortExtra\n");
  326.     }
  327.     else printf("Could not get the ViewPort\n");
  328.  
  329.     if (Myvp && vpe && cm && gotinfo)
  330.         return(Myvp);
  331.     else
  332.     {
  333.         DestroyViewPort(vp);
  334.         return(NULL);
  335.     }
  336. }
  337.  
  338.  
  339. /***********************************************************************************/
  340. /*                                                                                 */
  341. /* VOID DestroyBitMap(struct BitMap *Mybm, SHORT width, SHORT height, SHORT depth) */
  342. /*                                                                                 */
  343. /* Close and free everything to do with the BitMap                                 */
  344. /*                                                                                 */
  345. /***********************************************************************************/
  346.  
  347. VOID DestroyBitMap(struct BitMap *Mybm, SHORT width, SHORT height, SHORT depth)
  348. {
  349.     int i;
  350.  
  351.     if (Mybm)
  352.     {
  353.         for (i = 0; (i < depth); i++)
  354.         {
  355.             if (Mybm->Planes[i])
  356.                 FreeRaster(Mybm->Planes[i], width, height);
  357.         }
  358.         FreeVec(Mybm);
  359.     }
  360. }
  361.  
  362.  
  363. /***********************************************************************/
  364. /*                                                                     */
  365. /* struct BitMap *CreateBitMap(SHORT width, SHORT height, SHORT depth) */
  366. /*                                                                     */
  367. /* Create the BitMap.                                                  */
  368. /*                                                                     */
  369. /***********************************************************************/
  370.  
  371. struct BitMap *CreateBitMap(SHORT width, SHORT height, SHORT depth)
  372. {
  373.     /* Allocate a BitMap structure, initialise it, and allocate each plane. */
  374.  
  375.     struct BitMap *Mybm;
  376.     PLANEPTR allocated = (PLANEPTR) 1;
  377.     int i;
  378.  
  379.     if (Mybm = AllocVec(sizeof(struct BitMap), MEMF_CLEAR | MEMF_PUBLIC))
  380.     {
  381.         InitBitMap(Mybm, depth, width, height);
  382.         for (i = 0; ((i < depth) && (allocated)); i++)
  383.             allocated = (Mybm->Planes[i] = AllocRaster(width, height));
  384.  
  385.         if (allocated == NULL)
  386.         {
  387.             printf("Could not allocate all the planes\n");
  388.             DestroyBitMap(Mybm, width, height, depth);
  389.             Mybm = NULL;
  390.         }
  391.     }
  392.     else printf("Could not get BitMap\n");
  393.  
  394.     return(Mybm);
  395. }
  396.  
  397. /********************************************************************************/
  398. /*                                                                              */
  399. /* VOID ShowView(struct View *view, struct ViewPort *vp, struct BitMap *bm,    */
  400. /*                                                SHORT width, SHORT height)    */
  401. /*                                                                              */
  402. /* Assemble and display the View.                                               */
  403. /*                                                                              */
  404. /********************************************************************************/
  405.  
  406. VOID ShowView(struct View *view, struct ViewPort *vp, struct BitMap *bm,
  407.                                                SHORT width, SHORT height)
  408. {
  409.     /* Attach the BitMap to the ViewPort via a RasInfo.  Attach the ViewPort
  410.      * to the View.  Clear the BitMap, and draw into it by attaching the BitMap
  411.      * to a RastPort.  Then MakeVPort(), MrgCop() and LoadView().
  412.      * Just wait for the user to press <RETURN> before returning.
  413.      */
  414.  
  415.     struct RastPort *rp;
  416.     struct RasInfo *ri;
  417.  
  418.     if (rp = AllocVec(sizeof(struct RastPort), MEMF_CLEAR | MEMF_PUBLIC))
  419.     {
  420.         if (ri = AllocVec(sizeof(struct RasInfo), MEMF_CLEAR | MEMF_PUBLIC))
  421.         {
  422.             InitRastPort(rp);
  423.             ri->BitMap = rp->BitMap = bm;
  424.             vp->RasInfo = ri;
  425.             view->ViewPort = vp;
  426.  
  427.             /* render */
  428.             SetRast(rp, 0);        /* clear the background */
  429.             SetAPen(rp, ((1 << bm->Depth) - 1));    /* use the last pen */
  430.             Move(rp, 0, 0);
  431.             Draw(rp, width, 0);
  432.             Draw(rp, width, height);
  433.             Draw(rp, 0, height);
  434.             Draw(rp, 0, 0);
  435.  
  436.             /* display it */
  437.             MakeVPort(view, vp);
  438.             MrgCop(view);
  439.             LoadView(view);
  440.  
  441.             getchar();
  442.  
  443.             /* bring back the system */
  444.             RethinkDisplay();
  445.  
  446.             FreeVec(ri);
  447.         }
  448.         else printf("Could not get RasInfo\n");
  449.  
  450.         FreeVec(rp);
  451.     }
  452.     else printf("Could not get RastPort\n");
  453.  
  454. }
  455.  
  456.  
  457. /**********************************************************************/
  458. /*                                                                    */
  459. /* VOID main (int argc, char *argv[])                                 */
  460. /*                                                                    */
  461. /* Clone the Workbench View using Graphics Library calls.             */
  462. /*                                                                    */
  463. /**********************************************************************/
  464.  
  465. VOID main (int argc, char *argv[])
  466. {
  467.     struct Screen *wb;
  468.     struct View *Myview;
  469.     struct ViewPort *Myvp;
  470.     struct BitMap *Mybm;
  471.     ULONG ModeID;
  472.     ULONG IbaseLock;
  473.  
  474.     Init () ;        /* to open the libraries */
  475.  
  476.     /* To clone the Workbench using graphics calls involves duplicating
  477.      * the Workbench ViewPort, ViewPort mode, and Intuition's View.
  478.      * This also involves duplicating the DisplayClip for the overscan
  479.      * value, the colours, and the View position.
  480.      *
  481.      * When this is all done, the View, ViewPort, ColorMap and BitMap
  482.      * (and ViewPortExtra, ViewExtra and RasInfo) all have to be linked
  483.      * together, and the copperlists made to create the display.
  484.      *
  485.      * This is not as difficult as it sounds (trust me!)
  486.      */
  487.  
  488.     /* First, lock the Workbench screen, so no changes can be made to it
  489.      * while we are duplicating it.
  490.      */
  491.     if (wb = LockPubScreen("Workbench"))
  492.     {
  493.         /* Find the Workbench's ModeID. This is a 32-bit number that
  494.          * identifies the monitor type, and the display mode of that monitor.
  495.          */
  496.         ModeID = GetVPModeID(&wb->ViewPort);
  497.  
  498.         /* We need to duplicate Intuition's View structure, so lock IntuitionBase
  499.          * to prevent the View changing under our feet.
  500.          */
  501.         IbaseLock = LockIBase(0);
  502.         if (Myview = DupView(&IntuitionBase->ViewLord, ModeID))
  503.         {
  504.             /* The View has been cloned, so we don't need to keep it locked. */
  505.             UnlockIBase(IbaseLock);
  506.  
  507.             /* Now duplicate the Workbench's ViewPort. Remember, we still have
  508.              * the Workbench locked.
  509.              */
  510.             if (Myvp = DupViewPort(&wb->ViewPort, ModeID))
  511.             {
  512.                 /* Create a BitMap to render into. This will be of the
  513.                  * same dimensions as the Workbench.
  514.                  */
  515.                 if (Mybm = CreateBitMap(wb->Width, wb->Height, wb->BitMap.Depth))
  516.                 {
  517.                     /* Now we have everything copied, show something */
  518.                     ShowView(Myview, Myvp, Mybm, wb->Width-1, wb->Height-1);
  519.  
  520.                     /* Now free up everything we have allocated */
  521.                     DestroyBitMap(Mybm, wb->Width, wb->Height, wb->BitMap.Depth);
  522.                 }
  523.                 DestroyViewPort(Myvp);
  524.             }
  525.             DestroyView(Myview);
  526.         }
  527.         else
  528.         {
  529.             UnlockIBase(IbaseLock);
  530.         }
  531.         UnlockPubScreen(NULL, wb);
  532.     }
  533.     CloseAll () ;
  534. }
  535.